import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Esta clase representa a un panel, el cual dirige todo el proceso de juego entre jugadores.
 * @author Miguel Martinez Aguilar
 * @version 27 de Marzo del 2013
 */
public class Panel extends ScrollActor
{
    // Declaracion de variables de instancia
    private boolean jugar;// es un boleano que establece si el panel esta en juego.
    private boolean juegaEl;// es un boleano que establece si juega el primer jugador.
    private Lanzador lanzador;// es el objeto Lanzador.
    private Jugador oponente1;// es el jugador de la derecha.
    private Jugador oponente2;// es el jugador de la izquierda.
    private Movedor movedor;// es el objeto movedor.
    private Evaluador evaluador;// Es el objeto Evaluador.
    private int aux;// es una variable auxiliar que define si un jugador en turno ya puede jugar.
    private Puerta puerta;// es la puerta que da acceso al juego.
    private MenuGan ganador;// es el objeto MenuGan.
    private MenuNiveles anterior;// es uu menu de niveles. puede no existir.
    
    /**
     * Constructor de Panel.
     * @param uno: el jugador de la derecha.
     * @param dos: el jugador de la izquierda.
     * @param movedor: el objeto movedor, el cual mueve el escenario en cada turno.
     * @param puerta: la puerta que da acceso al juego (es un objeto).
     * @param menu: un menu de niveles, si es que el juego se desarrolla por niveles.
     */
    public Panel(Jugador uno, Jugador dos, Movedor movedor, Puerta puerta, MenuNiveles menu) 
    {
        jugar = false;
        juegaEl = true;
        lanzador = new Lanzador(this);
        oponente1 = uno;
        oponente2 = dos;
        this.movedor = movedor;
        aux = 0;
        evaluador = new Evaluador(this);
        this.puerta = puerta;
        ganador = null;
        this.anterior = menu;
    }

    /**
     * Este metodo permite a panel determinar el cambio de turno de los jugadores, y activar
     * el desplazamiento de la escena.
     */
    public void act() 
    {
        if(jugar){
            if(juegaEl){// turno del usuario
                if(!oponente1.turno()){
                    if(!movedor.SeMueve() && aux == 0){
                        movedor.ActivaMover();
                        aux = 1;
                    }
                    if(!movedor.SeMueve()){
                        oponente1.juega();
                        aux = 0;
                    }
                }
            }
            else{// turno del oponente
                if(!oponente2.turno()){
                    if(!movedor.SeMueve() && aux == 0){
                        movedor.ActivaMover();
                        aux = 1;
                    }
                    if(!movedor.SeMueve()){
                        oponente2.juega();
                        aux = 0;
                    }
                }
            }
        }
    }
    
    /**
     * Este metodo agrega elementos para el funcionamiento del juego
     */
    public void preparaJuego()
    {
        ScrollWorld mundo = super.getWorld();
        mundo.setPaintOrder(Jugador.class);
        mundo.addObject(lanzador, 669, 48);
        mundo.addObject(evaluador, this.getX(), 290);
        oponente1.setLocation(320, 58);
        oponente2.setLocation(1020, 58);
        oponente1.creaTablero(273,322,false);
        oponente2.creaTablero(1064,322,true);
        oponente1.preparar(lanzador,new CreaFlota(oponente1.entregaTablero(),this,false,oponente1.barcosOcultos()),106,116);
        oponente2.preparar(lanzador,new CreaFlota(oponente2.entregaTablero(),this,true,oponente2.barcosOcultos()),1231,116);
        this.cambiaTableros();
        oponente1.soyPrimero();
        mundo.setPaintOrder(Puerta.class);
        puerta.asignaPanel(this);
    }
    
    /**
     * Este metodo inicia el juego
     */
    public void comienzajuego()
    {
        aux++;
        if(aux == 2){
            jugar = true;
            aux = 0;
        }
    }
    
    /**
     * Este metodo modifica el valor de juegaEl.
     * @param val: boleano que indica si es el turno del jugador de la derecha.
     */
    public void cambiaTurno(boolean val)
    {
        juegaEl = val;
    }
    
    /**
     * Este metodo intercambia los tableros de los jugadores
     */
    public void cambiaTableros()
    {
        Tablero tab = oponente1.entregaTablero();
        oponente1.tomaTablero(oponente2.entregaTablero());
        oponente2.tomaTablero(tab);
    }
    
    /**
     * Este metodo agrega un barco a la lista correspondiente en Evaluador.
     * @param barco: el barco que se agregara.
     * @param bimg: el objeto imagen que representara al barco.
     * @param derecha: boleano que indica a que lista se agregara el barco (izquierda o derecha).
     */
    public void agregaBarco(Barco barco, BarcoImg bimg, boolean derecha) 
    {
        evaluador.agregaBarco(barco,bimg,derecha);
    }
    
    /**
     * Este metodo derrota un barco en la lista correspondiente en Evaluador.
     * @param derecha: boleano que indica a que lista se le quitara un barco destruido al evaluador.
     */
    public void derrotaBarco(boolean derecha)
    {
        evaluador.derrotar(derecha);
    }
    
    /**
     * Este metodo pide a Evaluador que explote un barco eliminado. <p>
     * Regresa un boleano que indica si se a destruido por completo un barco.
     */
    public boolean explotaBarco()
    {
        return evaluador.explotaBarco();
    }
    
    /**
     * Este metodo regresa el evaluador que contendra los barcos.
     */
    public Evaluador evaluador()
    {
        return evaluador;
    }

    /**
     * Este metodo declara un ganador.
     * @param val: boleano que indica que jugador gano (el de la izquierda o el de la derecha).
     */
    public void ganador(boolean val)
    {
        jugar = false;
        ScrollWorld mundo = super.getWorld();
        if(val)ganador = new MenuGan(puerta,oponente1,mundo);// gana el oponente1
        else ganador = new MenuGan(puerta,oponente2,mundo);// gana el oponente2
        mundo.setPaintOrder(Jugador.class);
        oponente1.terminaTurno();
        oponente2.terminaTurno();
        if(anterior != null)anterior.quienGano(val);
        this.agregaObj(ganador, 350, 250);
        ganador.prepara();
    }
    
    /**
     * Este metodo borra todos los elementos de juego del panel.
     */
    public void borraTodo()
    {
        ScrollWorld mundo = super.getWorld();
        this.quitaObj(ganador);
        movedor.borrador();
        java.util.List lista = mundo.getObjects(ScrollActor.class);
        int tam = lista.size();
        int i = 0;
        while(i < tam){
            Object obj = lista.get(i);
            mundo.removeObject((ScrollActor)obj);
            i++;
        }
        MenuJuego menu = new MenuJuego(puerta,anterior);
        mundo.addObject(menu,125,250);
        menu.prepara();
    }
}
